package com.frontop.terminal.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.ParserConfig;
import com.frontop.terminal.component.ResourcePublishing;
import com.frontop.terminal.constant.CommandConst;
import com.frontop.terminal.constant.CommonNumBerCodConst;
import com.frontop.terminal.constant.DownloadConst;
import com.frontop.terminal.constant.InterfaceConst;
import com.frontop.terminal.downloader.DownloadCenter;
import com.frontop.terminal.downloader.MultipleThreadDownloadTask;
import com.frontop.terminal.entity.File;
import com.frontop.terminal.entity.Message;
import com.frontop.terminal.entity.PlayList;
import com.frontop.terminal.entity.TerminalConfig;
import com.frontop.terminal.enums.HeaderEnum;
import com.frontop.terminal.model.bo.TerminalResourceBO;
import com.frontop.terminal.model.vo.RestResult;
import com.frontop.terminal.service.ICommandSerivce;
import com.frontop.terminal.util.ReadDataUtil;
import com.frontop.terminal.util.SystemMonitoringUtil;
import com.frontop.terminal.util.WriteDataUtil;
import com.frontop.terminal.vlcjplayer.VlcjPlayer;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * <p>
 * 媒体资源业务
 * </P>
 *
 * @author :CCC
 * @since :2021-06-08 10:11:00
 **/
@Slf4j
public class PlayListServiceImpl implements ICommandSerivce {

    private void comparisonFile(String result, List<File> localFile) {
        List<File> newFile = JSON.parseArray(result, File.class, ParserConfig.global);
        //读取本地文件列表比对忘记是否存在
        outer:
        for (File newF : newFile) {
            //本地文件列表不为空的话跟最新的文件对比那些数据不存在
            if (!localFile.isEmpty()) {
                for (File f : localFile
                ) {
                    //比对本地是否存在该记录
                    if (f.getId().equals(newF.getId())) {
                        //文件已经存在本地记录中同时不是正在下载状态那就重新下载
                        if (!f.getDownloadStatus().equals(DownloadConst.IN_PROGRESS)) {
                        } else {
                            //正在进行中的任务可以删除当前任务重新下载。因为可能会存在网络波动导致下载无响应
                            f.setDownloadStatus(DownloadConst.NOT_START);
                        }
                        continue outer;
                    }
                }
            }
            //不存在的记录添加到本地文件
            newF.setDownloadStatus(DownloadConst.NOT_START);
            //保证文件名称不重复
            String uuid = RandomUtil.randomStringUpper(4);
            String newName = newF.getName() + "_" + uuid;
            newF.setName(newName);
            localFile.add(newF);
        }

        //更新本地文件记录
        WriteDataUtil.write(localFile, ReadDataUtil.FILE_LIST_CODING);
    }

    @Override
    public RestResult executeWork(Message message) {
        //刷新播放列表命令
        if (CommandConst.REFRESH.equals(message.getCommand())) {
            try {
                //获取服务器配置地址拼装完整接口
                String url;
                String mac = SystemMonitoringUtil.getMacAddress();
                String result;

                //服务器返回的播放列表
                List<TerminalResourceBO> resourceBOList = new ArrayList<>();
                try {
                    url = Objects.requireNonNull(ReadDataUtil.getTerminalConfig()).getServerAddress() + InterfaceConst.GET_PUBLISH_RESOURCE_LIST;
                    result = HttpRequest.get(url)
                            //设置连接超时和响应超时时间
                            .timeout(3000)
                            .header(HeaderEnum.TERMINAL_TOKEN.getKey(), ReadDataUtil.getTerminalConfig().getAuthorizationCode())
                            .form("mac", mac)
                            .execute()
                            .body();

                    System.out.println("收到服务器返回的最新播放列表：" + result);

                    resourceBOList = JSON.parseArray(result, TerminalResourceBO.class);
                } catch (IORuntimeException e) {
                    log.error("获取已发布资源列表异常");
                } catch (JSONException e) {
                    log.error("获取已发布资源列表JSON转换异常{}", e.fillInStackTrace().toString());
                    e.printStackTrace();
                }


                if (!resourceBOList.isEmpty()) {

                    List<PlayList> serverPlays = new ArrayList<>(16);
                    resourceBOList.forEach(terminalResourceBO -> {
                        PlayList play = new PlayList();
                        play.setId(Long.parseLong(terminalResourceBO.getId()));
                        play.setName(terminalResourceBO.getResourceName());
                        play.setType(terminalResourceBO.getResourceType() == 6 ? 1 : 0);
                        play.setFileId(terminalResourceBO.getResourceId());
                        play.setSource(terminalResourceBO.getResourceSource() == 1 ? 0 : 1);
                        play.setLocation(terminalResourceBO.getResourceLocation());
                        serverPlays.add(play);
                    });

                    //获取本地的播放列表出来比对
                    List<PlayList> localPlays = ReadDataUtil.getPlayList();
                    //本地播放列表启动时存在空标识
                    boolean isNullLocalPlay = false;
                    //新的播放列表
                    List<PlayList> newPlays = new ArrayList<>(10);


                    if (Objects.isNull(localPlays) || localPlays.isEmpty()) {
                        if (Objects.isNull(localPlays)) {
                            localPlays = new ArrayList<>(10);
                        }
                        isNullLocalPlay = true;
                    }
                    //遍历文件Id，生成播放列表集合，方便以后扩展功能
                    fileIdsFor:
                    for (PlayList serverPlay : serverPlays) {
                        //跟本地播放列表比较是否不存在
                        for (PlayList localPlay : localPlays) {

                            //跟本地播放记录匹配
                            if (serverPlay.getId().equals(localPlay.getId())) {
                                newPlays.add(localPlay);
                                continue fileIdsFor;
                            }

                            //这个是匹配本地导入的资源
                            if (serverPlay.getId().equals(localPlay.getId()) && localPlay.getSource().equals(1)) {
                                newPlays.add(localPlay);
                                continue fileIdsFor;
                            }
                        }

                        newPlays.add(serverPlay);
                    }

                    //------------------------------------------------------处理本地文件-----------------------------------------------------

                    //获取本地文件记录
                    List<File> localFile = ReadDataUtil.getFile();

                    //为新的播放列表查找是否已经有下载完成的文件进行绑定(秒传)
                    if (Objects.nonNull(localFile) && !localFile.isEmpty()) {
                        PlayListFor:
                        for (PlayList p : newPlays) {
                            for (File f : localFile) {
                                //中控资源
                                if (p.getSource().equals(CommonNumBerCodConst.ZERO)
                                        && StrUtil.isEmpty(p.getLocation())
                                        && p.getFileId().equals(f.getId())) {

                                    //如果是已经下载完的文件，那判断本地是否存在这个文件
                                    if (f.getDownloadStatus().equals(DownloadConst.ACCOMPLISH)) {
                                        boolean existStatus = FileUtil.exist(f.getLocations());

                                        //存在的话计算文件大小是否下载完整
                                        if (existStatus) {
                                            Long fielSize = FileUtil.size(new java.io.File(f.getLocations()));

                                            //文件大小匹配，实现秒传
                                            if (fielSize.equals(f.getSize())) {
                                                p.setLocation(f.getLocations());
                                                //通知服务器更新发布状态
                                                MultipleThreadDownloadTask.updateMediaLinkState(p.getId());

                                                continue PlayListFor;
                                            }
                                        }

                                        log.warn("文件:" + f.getName() + ",ID:" + f.getId() + "\t本地不存在或损坏,稍后将重新下载");
                                        //本地不存在该文件或者文件下载不完整，设置状态重新下载
                                        f.setDownloadStatus(DownloadConst.NOT_START);
                                        f.setLocations(null);
                                    }
                                }
                            }
                        }
                    }

                    //写入文件
                    WriteDataUtil.write(newPlays, ReadDataUtil.PLAYLIST_LIST_CODING);

                    //如果播放列表不为空
                    if (!newPlays.isEmpty()) {
                        //获取文件id查询服务器
                        List<Long> ids = new ArrayList<>(10);
                        for (PlayList play : newPlays) {
                            if (StrUtil.isEmpty(play.getLocation())) {
                                ids.add(play.getFileId());
                            }
                        }

                        //fiel列表不为空再去请求
                        if (!ids.isEmpty()) {
                            try {
                                url = ReadDataUtil.getTerminalConfig().getServerAddress() + InterfaceConst.GET_FILE_LIST;
                                //请求文件详情列表
                                result = HttpRequest.get(url)
                                        //设置连接超时和响应超时时间
                                        .timeout(3000)
                                        .header(HeaderEnum.TERMINAL_TOKEN.getKey(), ReadDataUtil.getTerminalConfig().getAuthorizationCode())
                                        .form("ids", ids)
                                        .execute().body();

                                comparisonFile(result, localFile);
                            } catch (IORuntimeException e) {
                                log.error("获取已发布资源列表接口异常");
                            } catch (JSONException e) {
                                log.error("获取已发布资源列表接口JSON转换异常{}", e.fillInStackTrace().toString());
                                e.printStackTrace();
                            }

                        }

                        //-------------------------------------------------下载任务-----------------------------------------------------------

                        //存在下载任务标注
                        boolean existDownload = false;
                        //创建下载任务
                        assert localFile != null;
                        for (File f : localFile
                        ) {
                            //将未加入到下载任务的文件 || 未下载完成的任务添加进去
                            if (!f.getDownloadStatus().equals(DownloadConst.ACCOMPLISH)) {
                                //获取配置文件
                                TerminalConfig terminalConfig = ReadDataUtil.getTerminalConfig();
                                url = terminalConfig.getServerAddress() + InterfaceConst.TERMINAL_AGENT_RESOURCE_PART_DOWNLOAD + f.getId();

                                //获取当前日期 格式2021-7-23
                                String currentDate = FileUtil.FILE_SEPARATOR;
                                String localPath = terminalConfig.getResourceAddress() + currentDate;
                                //如果当前日期文件夹不存在就创建
                                if (!FileUtil.exist(localPath)) {
                                    FileUtil.mkdir(localPath);
                                }
                                //获取本地存储资源具体位置
                                localPath += f.getName();

                                //创建下载任务添加到下载中心
                                log.info("加入任务");
                                DownloadCenter.setExecutorService(new MultipleThreadDownloadTask(url, new java.io.File(localPath), f.getId(), CommonNumBerCodConst.ON));
                                existDownload = true;
                            }

                        }

                        //如果没有下载任务&&本地播放列表启动时空，说明终端实现了秒传，就自动播放一个视频
                        if (isNullLocalPlay && !existDownload) {
                            VlcjPlayer.play(ResourcePublishing.playListNullChke());
                        }
                    }

                } else {
                    //服务器返回的数据为空将清除本地文件数据
                    WriteDataUtil.write(new ArrayList<PlayList>(), ReadDataUtil.PLAYLIST_LIST_CODING);
                }
            } catch (NullPointerException e) {
                log.error("[TerminalConfig.json]配置文件可能不存在,终止运行");
                e.printStackTrace();
                System.exit(-1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return RestResult.success();
    }
}
